from flask import Blueprint, request, jsonify
from app.models import db
from app.models.material import Material
from app.utils.auth import require_permission

materials_bp = Blueprint('materials', __name__)

@materials_bp.route('', methods=['GET'])
@require_permission('material.view')
def get_materials():
    """获取材料列表"""
    try:
        page = request.args.get('page', 1, type=int)
        per_page = request.args.get('per_page', 10, type=int)
        search = request.args.get('search', '')
        category = request.args.get('category')
        low_stock = request.args.get('low_stock', type=bool)
        
        query = Material.query.filter_by(is_active=True)
        
        if search:
            query = query.filter(
                db.or_(
                    Material.name.contains(search),
                    Material.code.contains(search),
                    Material.supplier.contains(search)
                )
            )
        
        if category:
            query = query.filter_by(category=category)
        
        if low_stock:
            query = query.filter(Material.stock_quantity <= Material.min_stock)
        
        pagination = query.paginate(
            page=page, per_page=per_page, error_out=False
        )
        
        return jsonify({
            'materials': [material.to_dict() for material in pagination.items],
            'total': pagination.total,
            'pages': pagination.pages,
            'current_page': page
        }), 200
        
    except Exception as e:
        return jsonify({'error': str(e)}), 500

@materials_bp.route('', methods=['POST'])
@require_permission('material.create')
def create_material():
    """创建材料"""
    try:
        data = request.get_json()
        
        if not data.get('name'):
            return jsonify({'error': '材料名称不能为空'}), 400
        
        # 检查材料编码是否已存在
        if data.get('code'):
            if Material.query.filter_by(code=data['code']).first():
                return jsonify({'error': '材料编码已存在'}), 400
        
        material = Material(
            name=data['name'],
            code=data.get('code'),
            category=data.get('category'),
            unit=data.get('unit'),
            specification=data.get('specification'),
            stock_quantity=data.get('stock_quantity', 0),
            min_stock=data.get('min_stock', 0),
            unit_price=data.get('unit_price'),
            supplier=data.get('supplier')
        )
        
        db.session.add(material)
        db.session.commit()
        
        return jsonify({'material': material.to_dict()}), 201
        
    except Exception as e:
        db.session.rollback()
        return jsonify({'error': str(e)}), 500

@materials_bp.route('/<int:material_id>', methods=['PUT'])
@require_permission('material.edit')
def update_material(material_id):
    """更新材料"""
    try:
        material = Material.query.get_or_404(material_id)
        data = request.get_json()
        
        # 检查材料编码是否已被其他材料使用
        if 'code' in data and data['code'] != material.code:
            if Material.query.filter_by(code=data['code']).first():
                return jsonify({'error': '材料编码已存在'}), 400
        
        # 更新字段
        for field in ['name', 'code', 'category', 'unit', 'specification',
                     'stock_quantity', 'min_stock', 'unit_price', 'supplier', 'is_active']:
            if field in data:
                setattr(material, field, data[field])
        
        db.session.commit()
        
        return jsonify({'material': material.to_dict()}), 200
        
    except Exception as e:
        db.session.rollback()
        return jsonify({'error': str(e)}), 500

@materials_bp.route('/<int:material_id>', methods=['DELETE'])
@require_permission('material.delete')
def delete_material(material_id):
    """删除材料"""
    try:
        material = Material.query.get_or_404(material_id)
        
        db.session.delete(material)
        db.session.commit()
        
        return jsonify({'message': '材料删除成功'}), 200
        
    except Exception as e:
        db.session.rollback()
        return jsonify({'error': str(e)}), 500

@materials_bp.route('/<int:material_id>/stock', methods=['POST'])
@require_permission('material.stock_in', 'material.stock_out')
def update_material_stock(material_id):
    """更新物料库存"""
    try:
        material = Material.query.get_or_404(material_id)
        data = request.get_json()
        
        if not data.get('operation'):
            return jsonify({'error': '操作类型不能为空'}), 400
        
        if not data.get('quantity'):
            return jsonify({'error': '数量不能为空'}), 400
        
        operation = data['operation']  # 'in' 或 'out'
        quantity = float(data['quantity'])
        reason = data.get('reason', '')
        
        if operation not in ['in', 'out']:
            return jsonify({'error': '操作类型必须是 in 或 out'}), 400
        
        if quantity <= 0:
            return jsonify({'error': '数量必须大于0'}), 400
        
        # 更新库存
        if operation == 'in':
            material.stock_quantity += quantity
        else:  # operation == 'out'
            if material.stock_quantity < quantity:
                return jsonify({'error': '库存不足'}), 400
            material.stock_quantity -= quantity
        
        db.session.commit()
        
        return jsonify({
            'message': '库存操作成功',
            'material': material.to_dict()
        }), 200
        
    except Exception as e:
        db.session.rollback()
        return jsonify({'error': str(e)}), 500

@materials_bp.route('/categories', methods=['GET'])
@require_permission('material.view')
def get_categories():
    """获取材料分类列表"""
    try:
        categories = db.session.query(Material.category).filter(
            Material.category.isnot(None),
            Material.is_active == True
        ).distinct().all()
        
        return jsonify({
            'categories': [cat[0] for cat in categories if cat[0]]
        }), 200
        
    except Exception as e:
        return jsonify({'error': str(e)}), 500
